#include <stdio.h>
#include <string.h>
#include <malloc.h>
#include <stdbool.h>

#include "interaction.h"
#include "list.h"
#include "login_device.h"
#include "log.h"

static int read_user_file(struct list_head *user_head);
static int write_user_file(struct list_head *user_head);

/**
 * @brief   和用户信息链表中的账号和密码做对比
 * @param   user_id:用户输入的账号
 *          passwd:用户输入的密码
 *          user_head:用户信息链表的头指针
 * @return  ID_NO_MATCH:信息不匹配
 *          true:账号密码成功匹配
 */
int match_user_info(char *user_id, char *passwd,
                    struct list_head *user_head,
                    struct user *current_user)
{
    struct list_head *pos;
    struct user *scan_list;

    list_for_each (pos, user_head) {
        scan_list = list_entry(pos, struct user, list);
        if (!strcmp(scan_list->user_id, user_id)) {
            if (!strcmp(scan_list->passwd, passwd)) {
                return true;
            }
        }
    }

    return ID_NO_MATCH;
}

/**
 * @brief   检测用户账号是否重复
 * @param   user_id:用户输入的账号
 *          user_head:用户信息链表的头指针
 *          identity_number:用户输入的身份证
 * @return  USER_REPEAT:用户账号重复
 *          true:用户账号不重复
 */
int is_user_info_repeat(char *user_id, char *citizen_id,
                        char *phone_num, struct list_head *user_head)
{
    struct list_head *pos;
    struct user *scan_list;

    list_for_each (pos, user_head) {
        scan_list = list_entry(pos, struct user, list);
        if (!strcmp(scan_list->user_id, user_id)) {
            return USER_REPEAT;
        } else if (!strcmp(scan_list->citizen_id, citizen_id)) {
            return USER_REPEAT;
        } else if (!strcmp(scan_list->phone_num, phone_num)) {
            return USER_REPEAT;
        }
    }

    return true;
}

/**
 * @brief   管理员账号信息赋值
 */
void admin_init(struct admin *admin)
{
    admin->admin_id[0] = '1';
    admin->passwd[0] = '1';

    admin->admin_id[1] = '\0';
    admin->passwd[1] = '\0';
}

/**
 * @brief   管理员账号信息释放
 */
void admin_destroy(struct admin *admin)
{
    free(admin);
}

/**
 * @brief   用户链表初始化
 * @param   user_head:包含所有用户信息的指针
 * @return  true:正常运行
 *          false:读取文件失败
 */
int user_init(struct list_head *user_head)
{
    int ret;

    init_list_head(user_head);

    ret = read_user_file(user_head);
    if (ret == false) {
        return false;
    }

    return true;
}

/**
 * @brief   用户链表销毁
 * @param   user_head:包含所有用户信息的指针
 * @return  true:正常运行
 *          false:存入文件失败
 */
int user_destroy(struct list_head *user_head)
{
    struct list_head *pos, *n;
    struct user *scan_list;
    int ret;

    ret = write_user_file(user_head);
    if (ret != true) {
        DEBUG("WRITE USER FILE ERROR!");
        return false;
    }

    list_for_each_safe (pos, n, user_head) {
        list_del(pos);
        scan_list = list_entry(pos, struct user, list);
        free(scan_list);
    }

    return true;
}

/**
 * @brief   读取用户信息的文件
 * @param   user_head:包含所有用户信息的指针
 * @return  true:正常运行
 *          false:读取文件失败
 */
static int read_user_file(struct list_head *user_head)
{
    char user_id[USER_PASSWD_SIZE];
    char passwd[USER_PASSWD_SIZE];
    char name[NAME_SIZE];
    char citizen_id[CITIZEN_ID_SIZE];
    char phone_num[PHONE_NUM_SIZE];
    struct user *temp_user = NULL;
    FILE *save_file;

    /* 打开文件 */
    save_file = fopen("./lib/user_data.txt", "a+");
    if (!save_file) {
        save_file = fopen("../.././lib/user_data.txt", "a+");
        if (!save_file) {
            DEBUG("FAIL TO OPEN USER DATA FILE\n");
            return false;
        }
    }

    temp_user = (struct user *)malloc(sizeof(struct user));
    if (!temp_user) {
        DEBUG("FAIL TO MALLOC\n");
        fclose(save_file);
        return false;
    }

    /* 先把数据读取到temp里面 */
    fscanf(save_file, "%8s\t%8s\t%20s\t%8s\t%11s", user_id, passwd, name,
                                            citizen_id, phone_num);

    strncpy(temp_user->user_id, user_id, sizeof(user_id));
    strncpy(temp_user->passwd, passwd, sizeof(passwd));
    strncpy(temp_user->name, name, sizeof(name));
    strncpy(temp_user->citizen_id, citizen_id, sizeof(citizen_id));
    strncpy(temp_user->phone_num, phone_num, sizeof(phone_num));

    /* 将数据接入链表 */
    while (!feof(save_file)) {
        list_add_tail(&temp_user->list, user_head);

        temp_user = (struct user *)malloc(sizeof(struct user));
        if (!temp_user) {
            DEBUG("FAIL TO MALLOC\n");
            return false;
        }

        fscanf(save_file, "%8s\t%8s\t%20s\t%8s\t%11s", user_id, passwd,
                                            name, citizen_id, phone_num);

        strncpy(temp_user->user_id, user_id, sizeof(user_id));
        strncpy(temp_user->passwd, passwd, sizeof(passwd));
        strncpy(temp_user->name, name, sizeof(name));
        strncpy(temp_user->citizen_id, citizen_id, sizeof(citizen_id));
        strncpy(temp_user->phone_num, phone_num, sizeof(phone_num));
    }

    free(temp_user);
    fclose(save_file);
    return true;
}

/**
 * @brief   将用户信息写入文件
 * @param   user_head:包含所有用户信息的指针
 * @return  false:打开文件失败
 *          true:正常运行
 */
static int write_user_file(struct list_head *user_head)
{
    struct user *scan_list;
    struct list_head *pos;
    FILE *save_file;

    /* 打开文件 */
    save_file = fopen("./lib/user_data.txt", "w");
    if (!save_file) {
        save_file = fopen("../.././lib/user_data.txt", "w");
        if (!save_file) {
            DEBUG("FAIL TO OPEN USER DATA FILE\n");
            return false;
        }
    }

    /* 将链表中的数据依次写入文件 */
    list_for_each (pos, user_head) {
        scan_list = list_entry(pos, struct user, list);
        fprintf(save_file, "%s\t%s\t%s\t%s\t%s\n",
                            scan_list->user_id, scan_list->passwd,
                            scan_list->name, scan_list->citizen_id,
                            scan_list->phone_num);
    }

    fclose(save_file);
    return true;
}